/*
 * @(#)BasicPalette.java	0.1 2002-09-03
 * 
 * Copyleft 2002 Wonseok Shin, Taeksoo Jung
 * Anyone can get benefits from this.
 */
package cs348a.color;

import java.awt.Color;

/**
 * A <code>BasicPalette</code> is a basic implementation of the <code>Palette</code>.
 * 
 * @version	0.1
 * @author		Wonseok Shin, Taeksoo Jung
 * @since		0.1
 */
public class BasicPalette implements Palette {
	/** Name of the palette */
	protected String name;
	
	/** Map that maps indices to red components */
	private byte[] reds = new byte[SIZE];
	
	/** Map that maps indices to green components */
	private byte[] greens = new byte[SIZE];
	
	/** Map that maps indices to blue components */
	private byte[] blues = new byte[SIZE];

	/**
	 * Constructor for BasicPalette.
	 */
	public BasicPalette(String name, byte[] reds, byte[] greens, byte[] blues) {
		if (reds == null || greens == null || blues == null) {
			throw new IllegalArgumentException(
				"Reds: " + reds + ", Greens: " + greens + ", Blues: " + blues);
		}
		
		if (reds.length != SIZE || greens.length != SIZE || blues.length != SIZE) {
			throw new IllegalArgumentException(
				"Length of reds: " + reds.length 
				+ ", Length of greens: " + greens.length 
				+ ", Length of blues: " + blues.length);
		}

		// Sets the name.
		this.name = name;
		
		// Sets the components.
		System.arraycopy(reds, 0, this.reds, 0, SIZE);		
		System.arraycopy(greens, 0, this.greens, 0, SIZE);		
		System.arraycopy(blues, 0, this.blues, 0, SIZE);		
	}

	/**
	 * Converts the given palette into the <code>BasicPalette</code> and returns it.
	 * 
	 * @param palette the given palette
	 * @return BasicPalette the basic palette
	 */
	public static BasicPalette valueOf(Palette palette) {
		if (palette instanceof BasicPalette) {
			return (BasicPalette) palette;
		} else {
			return new BasicPalette(
				palette.toString(), 
				palette.getRedComponents(), 
				palette.getGreenComponents(), 
				palette.getBlueComponents());
		}
	}
	
	/**
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return name;
	}
	
	/**
	 * Cuts off the given double value into the range between 0 and 255.
	 * 
	 * @param f the given double value
	 * @return byte adjusted byte value
	 */
	protected static byte cutOff(double f) {
		if (f < 0.0) {
			return 0;
		} else if (f > 255) {
			return (byte) 255;
		} else {
			return (byte) f;
		}
	}

	/**
	 * @see com.psia.core.graphics.Palette#getRedComponents()
	 */
	public final byte[] getRedComponents() {
		// Makes a defensive copy.
		return (byte[]) reds.clone();
	}

	/**
	 * @see com.psia.core.graphics.Palette#getGreenComponents()
	 */
	public final byte[] getGreenComponents() {
		// Makes a defensive copy.
		return (byte[]) greens.clone();
	}

	/**
	 * @see com.psia.core.graphics.Palette#getBlueComponents()
	 */
	public final byte[] getBlueComponents() {
		// Makes a defensive copy.
		return (byte[]) blues.clone();
	}

	/**
	 * @see com.psia.core.palette.Palette#getColor(int)
	 */
	public final Color getColor(int index) {
		if (index < 0) {
			index = 0;
		} else if (index >= SIZE) {
			index = SIZE - 1;
		}

		return new Color(0xff & reds[index], 0xff & greens[index], 0xff & blues[index]);
	}

	/**
	 * @see com.psia.core.palette.Palette#getRed(int)
	 */
	public byte getRed(int index) {
		if (index < 0) {
			index = 0;
		} else if (index >= SIZE) {
			index = SIZE - 1;
		}

		return reds[index];
	}

	/**
	 * @see com.psia.core.palette.Palette#getGreen(int)
	 */
	public byte getGreen(int index) {
		if (index < 0) {
			index = 0;
		} else if (index >= SIZE) {
			index = SIZE - 1;
		}

		return greens[index];
	}

	/**
	 * @see com.psia.core.palette.Palette#getBlue(int)
	 */
	public byte getBlue(int index) {
		if (index < 0) {
			index = 0;
		} else if (index >= SIZE) {
			index = SIZE - 1;
		}

		return blues[index];
	}
}
